//
//  CurrencyExchangeViewModel.swift
//  Exchange
//
//  Created by 孟祥群 on 2018/5/31.
//  Copyright © 2018年 common. All rights reserved.
//

import UIKit
enum refreshStyle {
    case refreshAll
    case refreshAsset
    case refreshKind
}
class CurrencyExchangeViewModel: BaseViewModel {
    @objc dynamic var refreshBool:Bool = false // kvo监听
    @objc dynamic var assetBool:Bool = false // kvo监听 资产
    var selectCurrentPiceBool:Bool = false //标记选中的是当前最新成交价
    //交易对发生变化 刷新view
    @objc dynamic var changePair:Bool = false {
        didSet {
            self.selectPrice = ""
            self.cashNumber = "0.00"
            self.archiveRegular()
            self.changeFirst(states: true)
            let nameArr = currentPairModel.name.components(separatedBy: "/")
            if nameArr.count > 1 {
                sourceCoin = nameArr.last!
                tradeCoin = nameArr.first!
                isPairBool = true
            }else {
                sourceCoin = ""
                tradeCoin = ""
                isPairBool = false
            }
        }
    }
    @objc dynamic var coinOrder:Bool = false //交易订单
    var currentPairModel:MarketCoinModel = MarketCoinModel() //当前选中的币种信息
    var sourceCoin:String = "" //币对 last
    var tradeCoin:String = "" //币对 first
    var isPairBool:Bool = false //判断币对名称是否正确
    
    var selectPairName = "" //选择的币种名称
    var digit:String? //小数位数
    var currentData:[String : Any] = [:] //当前最新数据源
    var depModel:DepthModel? //整理深度model
    var selectPrice:String = "" //选中的价格
    var selectStates:Bool = false //标记买入 false 或 卖出 true
    var appearFirstBool:Bool = false //viewwillappear  刷新价格赋值
    
    var tradeModel:TradeCoinModel = TradeCoinModel() //目标币中的交易信息
    var sourceModel:TradeCoinModel = TradeCoinModel() //交易币种的交易信息
    
    var currentDeleteModel:CoinOrderModel = CoinOrderModel() //最新移除的model
    
    //清空 深度数据
    var isRemoveDepthData:Bool?  {
        didSet {
            self.depModel?.depthBigNumber = "0"
            self.depModel?.depUpArr.removeAll()
            self.depModel?.deptDownArr.removeAll()
        }
    }
    
    //刷新tick 修改
    var isRefreshPair:Bool = false {
        didSet {
            self.changePairStates(states: isRefreshPair)
        }
    }
    
    var isRefreshDepth:Bool = false {
        didSet {
            self.changeDepthStates(states: isRefreshDepth)
        }
    }
    
    
//    var semaphore =  DispatchSemaphore(value: 1)
    var calculationPrice:Double = 0.000001 //加减改变的单位
    var coinAssetModel:AssetModel = AssetModel() //资产
    var cashNumber:String = "0.00" //买入 /卖出的数量
    var totalTradeMoney = "0.00" //交易额
    
    var isSwitch:Bool = false //是否正在切换
    
    var coinBigNumber:String = "0.00"
    
    var value:Double = 0.00 //滑竿滑动的value
    
    var isMarketBool:Bool = false //限价 false 市价 true
    
    var passWord = ""
    
    var coinOrderArr:[CoinOrderModel] = []
    //当前的委托单
    var currentOder:CoinOrderModel = CoinOrderModel()
    
    var isNeedRefreshHistory:Bool = false
    
    var selectOrderModel:CoinOrderModel = CoinOrderModel()
    
    var regularModel:CoinRegularModel =  CoinRegularModel() //币种对应的规则
    
    //串行队列
    let group  = DispatchGroup()
    let quene = DispatchQueue(label: "queuename")
    
    lazy var dateArr:Array<AssetModel> = {
        let array:Array<AssetModel> = []
        return array
    }()
    
    lazy var tradeOrderRequest : TradeOrderRequest = {
        let api = TradeOrderRequest()
        api.dataReformer = self
        api.paramSource = self
        api.delegate = self
        return api
    }()
    
    lazy var request: AssetRequest = {
        let api = AssetRequest()
        api.type = .coinType
        api.dataReformer = self
        api.paramSource = self
        api.delegate = self
        return api
    }()
    
    lazy var cancelOrderRequest: CancelOrederRequest = {
        let api = CancelOrederRequest()
        api.dataReformer = self
        api.paramSource = self
        api.delegate = self
        return api
    }()
    
    lazy var legalRequest: LeverRequest = {
        let api = LeverRequest()
        api.dataReformer = self
        api.paramSource = self
        api.delegate = self
        return api
    }()
    
    lazy var depathSort:DepathSort =  {
         let sort = DepathSort()
         return sort
    }()
    
    override init(controller: BaseViewController)
    {
        super.init(controller: controller)
        if self.regularModel.priceDigit == 8 {
            
            digit = String(format: "%d", 0)
        }
        self.depModel = DepthModel()
    }
    
    
    /// 整理数据源 转换深度
    ///
    /// - Parameter data: 数据源
    func changeDepth(data: [String : Any]) {
        var current:[String : Any] = [:]
        current = data
        if current["cmd"] as? String != "depth" {return}
        if current["data"] == nil {return}
        quene.async(group: group, qos: .default, flags: []) {
//        self.semaphore.wait()
        self.currentData = current
            if ((current["data"] as? [String : AnyObject?]) != nil) {
                self.depModel?.metadata = current["data"] as! [String : AnyObject?]
            }else {
                return
            }
        guard let str  = data["symbol"] as? String else {
            return
        }
        if str.replacingOccurrences(of: "_", with: "/") != APPTransactionPair.default.selectPairModel.name {
            self.depModel?.metadata = [:]
            self.isRemoveDepthData = true
             DispatchQueue.main.async {
            self.refreshBool = true
            }
            return
        }
            if (self.depModel?.metadata["tick"] as? [String:Any]) != nil {
             if self.depModel?.metadata["tick"]!!["price"] as? Double != nil {
                let price:Double =  self.depModel?.metadata["tick"]!!["price"] as! Double
                APPTransactionPair.default.selectPairModel.price = price
                DispatchQueue.main.async {
                (self.controller as? CurrencyExchangeViewController)?.currencyView.changeCurrentPrice()
                }
             }
          }
        //整理上下游数据
        self.depathSort.sortDepth(model:self.depModel!, digit: Int(self.digit!)!)
        DispatchQueue.main.async {
            guard let str  = data["symbol"] as? String else {
                return
            }
            if str.replacingOccurrences(of: "_", with: "/") != APPTransactionPair.default.selectPairModel.name {
                self.isSwitch = true
            }else {
                self.isSwitch = false
            }
            
            self.refreshBool = true
        }
     }
    }
    
    /// 获取币币资产
    ///
    /// - Parameter
    func archiveInformation()  {
        CYMBShow.openIndicator(message: nil, view: self.controller?.view)
        self.dateArr.removeAll()
        self.request(request: request, success: {[weak self] (result) in
            CYMBShow.colseIndicator(view: self?.controller?.view)
            let dic:[String:Any]? = result != nil ? result : nil
            if dic == nil {
                return
            }
            if dic?["data"] as? Array<[String : Any]> == nil  {
                return
            }
            
            let array:Array<[String : Any]> = dic?["data"] as! Array<[String : Any]>
            for dic in array {
                let model = AssetModel(JSON: dic)
                if model != nil {
                    self?.dateArr.append(model!)
                }
            }
            self?.refreshBool = true
            self?.assetBool = true
            
        }) {[weak self] (response) in
            CYMBShow.colseIndicator(view: self?.controller?.view)
        }
    }
    
    /// 获取资产
    ///
    /// - Returns: 币种对应的数量
    func coinNumber() -> String{
        coinAssetModel  = AssetModel()
        if APPTransactionPair.default.selectPairModel.name.components(separatedBy: "/").count > 1 {
            let name =  !selectStates ? APPTransactionPair.default.selectPairModel.name.components(separatedBy: "/").last :
            APPTransactionPair.default.selectPairModel.name.components(separatedBy: "/").first
            for model in self.dateArr {
                if model.coinCode == name {
                    coinAssetModel = model
                    let number =  self.archiveDigitNumber(isNumber:false,isTradeAmount:false)
                    return String(format: "%@%@%@",kText("可用"),CYCalculate.cy_intercept(number: model.currentAmount, digit: number)!, model.coinCode)
                }
            }
            return String(format: "%@0%@", kText("可用"),name != nil ? name! : "")
            
        }else {
            return kText("可用") + "0"
        }
    }
    
    /// 获取法币价格
    ///
    /// - Parameter coin: 数字货币金额
    /// - Returns: 法币价格
    func archiveLeveMoeny(coin:String) -> String {
        if coin == "" {
            return ""
        }
        if selectPrice.count == 0 {
            coinBigNumber = "0.0"
            return ""
        }
        if Double(selectPrice)! == 0 {
            coinBigNumber = "0.0"
            return ""
        }
        if APPTransactionPair.default.selectPairModel.name.components(separatedBy: "/").count > 1 {
            let name =   APPTransactionPair.default.selectPairModel.name.components(separatedBy: "/").last != nil ? APPTransactionPair.default.selectPairModel.name.components(separatedBy: "/").last : ""
            let money =  AppContext.default.archiveLegalPrice(coinKind: AppCacheInfo.default.currency, legalKind: name!)
            let levelMoeny = CYCalculate.cy_multiplying(firstNumber: coin, lastNumber: money, digit: 2)
            
            return String(format: "≈%@%@", levelMoeny,AppCacheInfo.default.currency)
        }
        return ""
    }
    
    func archiveBigNumber() {
        //当前价格可购买的最大数量
        //市价买入 交易额
        let number =  self.archiveDigitNumber(isNumber:true,isTradeAmount:false)
        if isMarketBool && !selectStates {
            coinBigNumber = CYCalculate.cy_intercept(number: coinAssetModel.currentAmount, digit: number)!
            return
        }
        coinBigNumber = !selectStates ? CYCalculate.cy_dividing(firstNumber: coinAssetModel.currentAmount, lastNumber: selectPrice.count != 0 ? selectPrice : 0.00 , digit: number) :
            CYCalculate.cy_intercept(number: coinAssetModel.currentAmount, digit: number)!
    }
    
    
    
    /// 获取不同币种截位的单位
    ///
    /// - Parameters:
    ///   - isNumber: 是否是数量
    ///   - isTradeAmount: 是否是交易额
    /// - Returns: 结果
    func archiveDigitNumber(isNumber:Bool,isTradeAmount:Bool = false) -> Int{
        if isMarketBool && !selectStates {
            return self.regularModel.priceDigit
        }
        if !selectStates {
            if isNumber {
               return self.regularModel.numberdigit
            }else {
                return self.regularModel.priceDigit
            }
        }else {
            if isTradeAmount {
                return self.regularModel.priceDigit
            }else {
                return self.regularModel.numberdigit
            }
        }
    }
    
    
    func archiveTransactionPair() {
        
    }
    
    func archiveDigitArr() -> [String] {
        var digitArr:[String] = []
        if self.regularModel.priceDigit < 1 {
            return []
        }
        for i in 1 ... self.regularModel.priceDigit {
            digitArr.append(String(format: "%d", i))
        }
        return digitArr.reversed()
    }
    
    
    func changePrice(price:String) {
        if price.count == 0 {
            selectPrice = "0"
            return
        }
         selectPrice = CYCalculate.cy_intercept(number: price, digit: regularModel.priceDigit)!
    }
    
    /// 获取买入最低价格
    ///
    /// - Returns: 最低价格
    public func archiveSmallPrice() -> String {
        if self.depModel?.depUpArr.count == 0 {
            return ""
        }
        let lastNumber = (self.depModel?.depUpArr.count)! >= 5 ? 4 : (self.depModel?.depUpArr.count)! - 1
        let model:DepdetailModel  =  (self.depModel?.depUpArr[lastNumber])!
        selectPrice = CYCalculate.cy_intercept(number: model.price, digit: regularModel.priceDigit)!
        return selectPrice
    }
    
    /// 获取卖出最大价格
    ///
    /// - Returns: 最大价格
    public func archiveBigPrice() -> String {
        if self.depModel?.deptDownArr.count == 0 {
            return ""
        }
        let model:DepdetailModel  =  (self.depModel?.deptDownArr[0])!
        selectPrice = CYCalculate.cy_intercept(number: model.price, digit: regularModel.priceDigit)!
        return selectPrice
    }
    
    
    /// 获取币对交易规则
    func archiveRegular() {
        self.regularModel = APPTransactionPair.default.archiveCoinPairRegular(name: self.currentPairModel.name)
    }
    
    /// 修改第一次进入刷新数据状态
    ///
    /// - Parameter states: 状态
    func changeFirst(states:Bool) {
        appearFirstBool = states
    }
    
    /// 修改加减的数字
    ///
    /// - Parameter digit: 小数位数
    func changeCalculationPrice(digit:Int) {
        var unitPrice:Double = 1
        for _ in 0..<digit {
            unitPrice = unitPrice / 10
        }
        calculationPrice = unitPrice
    }
    
    //加
    func addPrice() -> String{
        if selectPrice.count == 0 {
            return ""
        }
        selectPrice = CYCalculate.cy_add(firstNumber: selectPrice, lastNumber: regularModel.tickSize,
                                         digit: regularModel.priceDigit,isNeedUp: false)
        return selectPrice
    }
    
    func minus() -> String {
        if selectPrice.count == 0 {
            return ""
        }
       selectPrice = CYCalculate.cy_minus(firstNumber: selectPrice, lastNumber: regularModel.tickSize,
                                          digit: regularModel.priceDigit,isNeedUp: false)
        
        if Double(selectPrice)! <= 0.00 {
            return "0"
        }
        return selectPrice
    }
    
    
    func calculateTradeMoney() -> String{
        totalTradeMoney = "0.00"
        if cashNumber.count == 0 {
            return "\(kText("交易额"))---"
        }
        if selectPrice.count == 0 {
            return "\(kText("交易额"))---"
        }
        let number =  self.archiveDigitNumber(isNumber: false,isTradeAmount: true)
        totalTradeMoney = CYCalculate.cy_multiplying(firstNumber: cashNumber, lastNumber: selectPrice, digit: 8)
        if APPTransactionPair.default.selectPairModel.name.components(separatedBy: "/").count > 1 {
            let name =   APPTransactionPair.default.selectPairModel.name.components(separatedBy: "/").last
            return String(format: "%@%@%@", kText("交易额"),totalTradeMoney,name!)
        }
        return "\(kText("交易额"))---"
    }
    
    
    func tradeOrder() {
        tradeOrderRequest.isMarketBool = isMarketBool
        self.request(request: tradeOrderRequest, success: {[weak self] (result) in
            CYMBShow.showMessage(kText("下单成功"))
            self?.dateArr.removeAll()
            self?.archiveInformation()
            self?.selectPrice = ""
            self?.cashNumber = "0.00"
            self?.appearFirstBool = true
            self?.refreshBool = true
            self?.changePair = true
            
        }) { (response) in
            CYMBShow.showMessage(response.errorMsg)
        }
    }
    
    func cancelOrder() {
        cancelOrderRequest.isCoinOrder  = true
        self.request(request: cancelOrderRequest, success: {[weak self] (result) in
            if self?.selectOrderModel.status == 3 {
               CYMBShow.showMessage(kText("已在撤销中"))
            }else {
            CYMBShow.showMessage(kText("撤销委托单申请提交成功"))
            }
        }) { (response) in
            if  response.errorMsg.count != 0  {
            CYMBShow.showMessage(response.errorMsg)
            }
        }
    }
    
    /// 获取币种规则
    func archiveCoinRegular(semaphore:DispatchSemaphore? = nil) {
        self.regularModel = CoinRegularModel()
        self.request(request: legalRequest, success: {[weak self] (result) in
            if semaphore != nil {
                semaphore?.signal()
            }
            if result == nil {
                return
            }
            guard let dic = result!["data"] as? [String:Any]? else {
                return
            }
            if dic == nil {
                return
            }
            self?.regularModel = CoinRegularModel(JSON: dic!)!
            
        }) {[weak self] (response) in
            if semaphore != nil {
                semaphore?.signal()
            }
        }
        
    }
    
}

extension CurrencyExchangeViewModel {
    
    /// 订阅推送
    ///
    /// - Parameter states: 订阅 or 取消
    func changePairStates(states:Bool)  {
        let symbols = currentPairModel.name
        if symbols.count == 0 {
            return
        }
        let nameArr = symbols.components(separatedBy: "/")
        if nameArr.count < 2 {
            return
        }
        if nameArr.last == nil {
            return
        }
        if states == true {
            APPTransactionPair.default.subscribeSingleCurrency(pairName: currentPairModel.name)
        }else {
            APPTransactionPair.default.cancelScribeSingleCurrency(pairName: currentPairModel.name)
        }
        
    }
    
    
    /// 校验限价单价
    ///
    /// - Returns: 结果
    func checkLimitPrice() -> Bool {
        if self.selectPrice.count == 0 {
            CYMBShow.showMessage(kText("请选择交易单价"))
            return false
        }
        if Double(self.selectPrice)! < self.regularModel.minPrice {
            CYMBShow.showMessage(kText("交易单价不能小于最低单价"))
            return false
        }
        if self.regularModel.maxPrice != 0.00 {
            if Double(self.selectPrice)! > self.regularModel.maxPrice {
                CYMBShow.showMessage(kText("交易单价不能大于最高单价"))
                return false
            }
        }
        ///判断上下幅度
        if self.currentPairModel.price != 0 && self.regularModel.increase != 0.0{
            let maxPrice = self.currentPairModel.price * (1 + self.regularModel.increase/100)
            let minPrice = self.currentPairModel.price * (1 - self.regularModel.increase/100)
            let comPareResult = CYCalculate.campare(firstNumber: Double(self.selectPrice)!, lastNumber: maxPrice)
            let secResult = CYCalculate.campare(firstNumber: Double(self.selectPrice)!, lastNumber: minPrice)
            if comPareResult == .larget || secResult == .small {
                CYMBShow.showMessage(kText("当前单价不在有效价格区间"))
                return false
            }
        }
        return true
    }
    
    /// 修改深度状态
    ///
    /// - Parameter states: true 订阅 false 取消
    func changeDepthStates(states:Bool) {
        let symbols = currentPairModel.name.replacingOccurrences(of: "/", with: "_")
        if symbols.count == 0 {
            return
        }
        let nameArr = symbols.components(separatedBy: "_")
        if nameArr.count < 2 {
            return
        }
        if nameArr.last == nil {
            return
        }
        
        var tickServer = ServerDepth()
        tickServer.symbol = symbols
        if states == true {
            SocketManager.shared.subscribe(server: tickServer)
        }else {
            SocketManager.shared.cancelSubscribe(server: tickServer)
        }
    }
}
extension CurrencyExchangeViewModel: RequestCallBack,RequestDataReformer,RequestParamSource {
    func reform(_ request: BaseRequest, _ data: [String : Any]?) {
        let block = self.successBlockDic.object(forKey: request.path())
        if ((block as? success) != nil) {
            (block as! success)(data)
        }
    }
    
    func requestDidSucess(_ request: BaseRequest) {
        
    }
    
    func requestDidFail(_ request: BaseRequest) {
        let block = self.failBlockDic.object(forKey: request.path())
        if ((block as? fail) != nil) {
            (block as! fail)(request)
        }
    }
    
    func requestParams(_ request: BaseRequest) -> [String : Any]? {
        var pramas: [String:Any] = [:]
        if let _ =  request as? TradeOrderRequest {
            pramas.updateValue(!selectStates ? 0 : 1, forKey: "position")
            let arr =  APPTransactionPair.default.selectPairModel.name.components(separatedBy: "/")
            if arr.count > 1 {
                pramas.updateValue(arr.last!, forKey: "sourceCoin")
                pramas.updateValue(arr.first!, forKey: "targetCoin")
            }
            pramas.updateValue(cashNumber, forKey: "tradeAmount")
            if !self.isMarketBool {
            pramas.updateValue(selectPrice, forKey: "tradePrice")
            }
            pramas.updateValue(isMarketBool ? 0 : 1, forKey: "tradeType")
            pramas.updateValue(passWord, forKey: "tradePwd")
            if AppInfo.default.userId != nil {
            pramas.updateValue(AppInfo.default.userId!, forKey: "userId")
            }
            
        }else if let _ = request as? CancelOrederRequest {
            pramas.updateValue(AppInfo.default.userId ?? 0, forKey: "userId")
            pramas.updateValue(selectOrderModel.orderNo, forKey: "orderNo")
        }else if let _ = request as? LeverRequest {
            pramas.updateValue(currentPairModel.name.count != 0 ? currentPairModel.name : "", forKey: "coinCode")
        }
        
        return pramas
    }
}
extension CurrencyExchangeViewModel {
    func changeOrderData(data:[String:Any])  {
        self.isNeedRefreshHistory = false
        guard let arr = (data["body"]  as? String)?.jsonObject as? [[String:Any]] else {
            return
        }
        if coinOrderArr.count == 0  {
            for dic in arr {
                let model = CoinOrderModel(JSON: dic)
                if model != nil {
                    model?.archiveAllPrice()
                    if self.checkModel(model: model!) {
                        //如果当前订单已经进历史 就不要了
                        if model?.orderNo != currentDeleteModel.orderNo {
                            coinOrderArr.append(model!)
                        }
                  }
                }
            }
        }else {
        for dic in arr {
            let model = CoinOrderModel(JSON: dic)
            if model != nil {
                model?.archiveAllPrice()
                if self.checkModel(model: model!) {
                coinOrderArr.insert(model!, at: 0)
                }
            }
         }
       }
        self.checkUpdateModel()
    }
    
    func checkModel(model:CoinOrderModel) -> Bool {
        var refresh:Bool = true
        (coinOrderArr as NSArray).enumerateObjects { (data, index, stop) in
            let newModel = data as? CoinOrderModel
            if newModel?.orderNo == model.orderNo {
                newModel?.status = model.status
                if (newModel?.dealAmount)! <= model.dealAmount {
                    newModel?.dealAmount = model.dealAmount
                }
                newModel?.dealTime = model.dealTime
                if model.status == 2 || model.status == 4 || model.status == 6 {
                    self.isNeedRefreshHistory = true
                    currentDeleteModel = newModel!
                    coinOrderArr.ch_removeObject(newModel!)
                }
                refresh = false
                stop.initialize(to: true)
            }
        }
        if model.status == 2 || model.status == 4 || model.status == 6 {
            return false
        }
        return refresh
    }
    
    
    /// 匹配当前币种对对应的当前委托订单
    func checkUpdateModel() {
        currentOder = CoinOrderModel()
        (coinOrderArr as NSArray).enumerateObjects { (data, index, stop) in
            let newModel = data as? CoinOrderModel
            let name = String(format: "%@/%@", (newModel?.targetCoin)!,(newModel?.sourceCoin)!)
            if APPTransactionPair.default.selectPairModel.name == name {
                currentOder = newModel!
                stop.initialize(to: true)
            }
        }
        self.coinOrder = true
    }
    
    
}
